#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
腾讯企业邮箱邮件清理工具
功能：连接腾讯企业邮箱，删除半年前的所有邮件

使用说明：
1. 确保已在腾讯企业邮箱中开启IMAP/SMTP服务
2. 使用授权码而非邮箱密码进行登录
3. 授权码需要在邮箱设置中生成
"""

import imaplib
import email
from datetime import datetime, timedelta
import sys

# 导入邮箱配置
try:
    from email_config import EMAIL_CONFIG
except ImportError:
    print("未找到配置文件 email_config.py，请创建该文件")
    sys.exit(1)

def connect_to_mailbox(username, password):
    """
    连接到腾讯企业邮箱
    
    Args:
        username (str): 邮箱用户名
        password (str): 邮箱授权码
        
    Returns:
        imaplib.IMAP4_SSL: IMAP连接对象
    """
    # 腾讯企业邮箱IMAP服务器配置
    imap_server = EMAIL_CONFIG.get('imap_server', 'imap.exmail.qq.com')
    imap_port = EMAIL_CONFIG.get('imap_port', 993)
    
    try:
        print("正在连接到腾讯企业邮箱...")
        # 创建SSL连接
        mail = imaplib.IMAP4_SSL(imap_server, imap_port)
        print("IMAP服务器连接成功")
        
        # 登录
        print("正在登录...")
        mail.login(username, password)
        print(f"成功连接到邮箱: {username}")
        return mail
    except imaplib.IMAP4.error as e:
        print(f"IMAP错误: {e}")
        print("可能的原因:")
        print("1. 用户名或授权码不正确")
        print("2. IMAP服务未开启")
        print("3. 账户被限制登录")
        sys.exit(1)
    except Exception as e:
        print(f"连接邮箱失败: {e}")
        print("请检查网络连接和服务器地址")
        sys.exit(1)

def select_mailbox(mail, mailbox="INBOX"):
    """
    选择邮箱文件夹
    
    Args:
        mail (imaplib.IMAP4_SSL): IMAP连接对象
        mailbox (str): 邮箱文件夹名称，默认为收件箱
        
    Returns:
        int: 邮件总数
    """
    try:
        print(f"正在选择邮箱文件夹: {mailbox}")
        # 选择邮箱文件夹
        status, messages = mail.select(mailbox)
        if status != 'OK':
            raise Exception(f"选择邮箱文件夹失败: {messages}")
        
        # 获取邮件总数
        if messages and len(messages) > 0:
            message_count = messages[0]
            if message_count is not None:
                if isinstance(message_count, bytes):
                    num_messages = int(message_count.decode('utf-8'))
                else:
                    num_messages = int(message_count)
                print(f"邮箱 '{mailbox}' 中共有 {num_messages} 封邮件")
                return num_messages
        
        print(f"邮箱 '{mailbox}' 中没有邮件")
        return 0
    except Exception as e:
        print(f"选择邮箱文件夹时出错: {e}")
        sys.exit(1)

def find_old_emails(mail, months_ago=6):
    """
    查找指定月份之前的邮件
    
    Args:
        mail (imaplib.IMAP4_SSL): IMAP连接对象
        months_ago (int): 几个月前的邮件，默认为6个月
        
    Returns:
        list: 符合条件的邮件ID列表
    """
    # 计算目标日期
    target_date = datetime.now() - timedelta(days=months_ago*30)
    target_date_str = target_date.strftime("%d-%b-%Y")
    
    print(f"查找 {target_date_str} 之前的所有邮件...")
    
    try:
        # 搜索指定日期之前的邮件
        # BEFORE条件会查找早于指定日期的邮件
        status, messages = mail.search(None, f'BEFORE {target_date_str}')
        if status != 'OK':
            raise Exception("搜索邮件失败")
            
        # 解析邮件ID
        if messages and len(messages) > 0:
            email_ids = messages[0].split() if isinstance(messages[0], bytes) else []
            print(f"找到 {len(email_ids)} 封 {months_ago} 个月前的邮件")
            return email_ids
        else:
            print("没有找到符合条件的邮件")
            return []
    except Exception as e:
        print(f"搜索邮件时出错: {e}")
        return []

def delete_emails(mail, email_ids, batch_size=50):
    """
    删除指定的邮件
    
    Args:
        mail (imaplib.IMAP4_SSL): IMAP连接对象
        email_ids (list): 要删除的邮件ID列表
        batch_size (int): 批量删除的数量，默认为50
    """
    if not email_ids:
        print("没有邮件需要删除")
        return
    
    print(f"开始删除 {len(email_ids)} 封邮件...")
    
    try:
        # 分批删除邮件以提高效率
        for i in range(0, len(email_ids), batch_size):
            batch = email_ids[i:i+batch_size]
            
            # 将邮件标记为删除
            # 使用逗号连接ID列表，形成类似 "1,2,3,4" 的格式
            if batch:
                id_list = b','.join(batch)
                status, response = mail.store(id_list, '+FLAGS', '\\Deleted')
                if status != 'OK':
                    print(f"标记删除邮件失败: {response}")
                    continue
                
                print(f"已标记删除第 {i+1} 到 {min(i+batch_size, len(email_ids))} 封邮件")
        
        # 执行真正的删除操作
        print("正在执行删除操作...")
        status, response = mail.expunge()
        if status == 'OK':
            print(f"成功删除 {len(email_ids)} 封邮件")
        else:
            print(f"删除操作完成，但可能存在问题: {response}")
        
    except Exception as e:
        print(f"删除邮件时出错: {e}")

def close_connection(mail):
    """
    关闭邮箱连接
    
    Args:
        mail (imaplib.IMAP4_SSL): IMAP连接对象
    """
    try:
        mail.close()
        mail.logout()
        print("邮箱连接已关闭")
    except Exception as e:
        print(f"关闭连接时出错: {e}")

def main():
    """主函数"""
    # 从配置文件获取邮箱信息
    USERNAME = EMAIL_CONFIG.get('username', '')
    PASSWORD = EMAIL_CONFIG.get('password', '')
    DELETE_MONTHS = EMAIL_CONFIG.get('delete_before_months', 6)
    BATCH_SIZE = EMAIL_CONFIG.get('batch_size', 50)
    
    if not USERNAME or not PASSWORD:
        print("请在 email_config.py 文件中配置用户名和密码")
        sys.exit(1)
    
    print("=" * 50)
    print("腾讯企业邮箱邮件清理工具")
    print("=" * 50)
    print("注意事项:")
    print("1. 请确保已在腾讯企业邮箱中开启IMAP/SMTP服务")
    print("2. 请使用授权码而非邮箱密码进行登录")
    print("3. 授权码需要在邮箱设置中生成")
    print()
    
    # 连接到邮箱
    mail = connect_to_mailbox(USERNAME, PASSWORD)
    
    try:
        # 选择收件箱
        num_messages = select_mailbox(mail, "INBOX")
        
        if num_messages == 0:
            print("收件箱中没有邮件")
            return
        
        # 查找指定月份前的邮件
        old_email_ids = find_old_emails(mail, DELETE_MONTHS)
        
        if not old_email_ids:
            print("没有找到符合条件的旧邮件")
            return
        
        # 显示将要删除的邮件数量
        print(f"\n将要删除 {len(old_email_ids)} 封邮件")
        print(f"这些邮件是{DELETE_MONTHS}个月前的旧邮件")
        
        # 确认是否删除
        confirm = input(f"\n确定要删除这 {len(old_email_ids)} 封邮件吗? (输入'y'确认删除): ")
        if confirm.lower() != 'y':
            print("取消删除操作")
            return
        
        # 删除邮件
        delete_emails(mail, old_email_ids, BATCH_SIZE)
        
    finally:
        # 关闭连接
        close_connection(mail)
    
    print("\n邮件清理完成!")

if __name__ == "__main__":
    main()